using System;
using Director.DomainModels;

namespace Director.Indicators.Basic
{
	public class ChartSimpleMovingAverage : SeriesChartIndicator
	{
		private readonly Func<Candle, decimal> _getValue;
		private decimal[] _data;

		public ChartSimpleMovingAverage(Func<Candle, decimal> getValue)
		{
			_getValue = getValue;
		}

		public int Length
		{
			get { return _data.Length; }
			set { _data = new decimal[value]; }
		}

		public override string ShortKindName
		{
			get { return "SMA"; }
		}

		public override void Calc(Candle[] candles)
		{
			Data = new decimal?[candles.Length];
			var i = 0;
			var j = 0;
			var l = Length;
			_data = new decimal[l];
			decimal s = 0;
			foreach (var candle in candles)
			{
				var v = _getValue(candle);
				_data[i] = v;
				s += v;
				if (j >= l)
				{
					Data[j] = s / l;
				}
				else
				{
					Data[j] = null;
				}
				i = (i + 1)%l;
				j++;
				s -= _data[i];
			}
		}
	}

	public class StrategySimpleMovingAverage : StrategyIndicator
	{
		private Func<Candle, decimal> _getValue;
		private int _len;
		private decimal[] _data;
		private decimal _sum;
		private int _cnt;

		public override string ShortKindName
		{
			get { return "SMA"; }
		}

		public StrategySimpleMovingAverage(Func<Candle, decimal> getValue, int len)
		{
			_getValue = getValue;
			_len = len;
			_data = new decimal[len];
		}

		protected override decimal? Calc(Candle candle)
		{
			var v = _getValue(candle);
			_sum += v;
			_data[_cnt % _len] = v;

			decimal? result = null;
			
			if (_cnt >= _len)
			{
				result = _sum / _len;
			}
			_cnt++;
			_sum -= _data[_cnt % _len];

			return result;
		}
	}
}